package com.farm.common.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 时刻区间转换为 LocalDateTime的时间期间
 *
 * @author farm
 * @date 2024
 **/
@Slf4j
public class TimeRangeUtils {

	/**
	 * 获取时间啊区间
	 * @param between 17:00:00,20:00:00
	 * @param now
	 * @return
	 */
	public static Map<String, String> getTimeRange(String between, LocalDateTime now) {
		// 有效服务工单开始时间
		String start = StringRange.getOne(between, 0);
		LocalDateTime startTime;
		if (ObjectUtil.isEmpty(start)){
			startTime = LocalDateTimeUtil.beginOfDay(now);
			start = "00:00:00";
		}else{
			int hour1 = Integer.parseInt(ObjectUtil.isEmpty(StringRange.getOne(start, 0,":"))? String.valueOf(0) :StringRange.getOne(start, 0,":"));
			hour1 = hour1>23||hour1<0?0:hour1;
			int minute1 = Integer.parseInt(ObjectUtil.isEmpty(StringRange.getOne(start, 1,":"))? String.valueOf(1) :StringRange.getOne(start, 1,":"));
			minute1 = minute1>59||minute1<0?0:minute1;
			int second1 = Integer.parseInt(ObjectUtil.isEmpty(StringRange.getOne(start, 2,":"))? String.valueOf(2) :StringRange.getOne(start, 2,":"));
			second1 = second1>59||second1<0?0:second1;

			startTime = now.withHour(hour1).withMinute(minute1).withSecond(second1);

			start = StrUtil.format("{}:{}:{}",String.format("%02d", hour1),String.format("%02d",minute1),String.format("%02d", second1));
		}

		// 有效服务工单结束时间
		String end = StringRange.getOne(between, 1);
		LocalDateTime endTime;
		if (ObjectUtil.isEmpty(end)){
			endTime = LocalDateTimeUtil.endOfDay(now);
			end = "23:59:59";
		}else{
			int hour2 = Integer.parseInt(ObjectUtil.isEmpty(StringRange.getOne(end, 0,":"))? String.valueOf(0) :StringRange.getOne(end, 0,":"));
			hour2 = hour2>23||hour2<0?23:hour2;
			int minute2 = Integer.parseInt(ObjectUtil.isEmpty(StringRange.getOne(end, 1,":"))? String.valueOf(1) :StringRange.getOne(end, 1,":"));
			minute2 = minute2>59||minute2<0?59:minute2;
			int second2 = Integer.parseInt(ObjectUtil.isEmpty(StringRange.getOne(end, 2,":"))? String.valueOf(2) :StringRange.getOne(end, 2,":"));
			second2 = second2>59||second2<0?59:second2;

			endTime = now.withHour(hour2).withMinute(minute2).withSecond(second2);

			end = StrUtil.format("{}:{}:{}",String.format("%02d", hour2),String.format("%02d", minute2),String.format("%02d", second2));
		}

		HashMap<String, String> result = new HashMap<>();

		result.put("startTime",LocalDateTimeUtil.format(startTime, DatePattern.NORM_DATETIME_PATTERN));
		result.put("endTime",LocalDateTimeUtil.format(endTime, DatePattern.NORM_DATETIME_PATTERN));
		result.put("range",StrUtil.format("{}~{}",start,end));
		return result;
	}

	/**
	 * 时间区间判断，包含左右边界
	 */
	public static boolean isTimeBetween(LocalDateTime startTime, LocalDateTime endTime, LocalDateTime targetTime) {
		return targetTime.isAfter(startTime) && targetTime.isBefore(endTime) || targetTime.isEqual(endTime) || targetTime.isEqual(startTime);
	}

	/**
	 * 时间区间判断，不包含左右边界
	 */
	public static boolean isTimeBetweenBothOpen(LocalDateTime startTime, LocalDateTime endTime, LocalDateTime targetTime) {
		return targetTime.isAfter(startTime) && targetTime.isBefore(endTime);
	}

	/**
	 * 时间区间判断，包含左边界
	 */
	public static boolean isTimeBetweenLeft(LocalDateTime startTime, LocalDateTime endTime, LocalDateTime targetTime) {
		return targetTime.isAfter(startTime) && targetTime.isBefore(endTime) || targetTime.isEqual(startTime);
	}

	/**
	 * 时间区间判断，包含右边界
	 */
	public static boolean isTimeBetweenRight(LocalDateTime startTime, LocalDateTime endTime, LocalDateTime targetTime) {
		return targetTime.isAfter(startTime) && targetTime.isBefore(endTime) || targetTime.isEqual(endTime);
	}

	/**
	 * 获取当前一周时间
	 * @return
	 */
	public static List<LocalDate> getCurrentWeekDates() {
		List<LocalDate> weekDates = new ArrayList<>();
		LocalDate today = LocalDate.now();

		// 获取当前日期是本周的第几天
		int currentDayOfWeek = today.getDayOfWeek().getValue();

		// 计算当前周的开始和结束日期
		LocalDate startOfWeek = today.minusDays(currentDayOfWeek - 1);
		LocalDate endOfWeek = today.plusDays(7 - currentDayOfWeek);

		// 添加本周每一天的日期到列表中
		LocalDate currentDate = startOfWeek;
		while (!currentDate.isAfter(endOfWeek)) {
			weekDates.add(currentDate);
			currentDate = currentDate.plusDays(1);
		}

		return weekDates;
	}

	/**
	 * 获取近一周时间
	 * @return
	 */
	public static List<LocalDate> getRecentSevenDays() {
		List<LocalDate> recentDays = new ArrayList<>();
		LocalDate now = LocalDate.now().minusDays(6);

		for (int i = 0; i < 7; i++) {
			LocalDate day = now.plusDays(i);
			recentDays.add(day);
		}

		return recentDays;
	}

	public static LocalDateTime getStartOfMonth(String monthString) {
		LocalDate date = LocalDate.parse(monthString + "-01");
		return LocalDateTime.of(date, LocalTime.MIN);
	}

	public static LocalDateTime getEndOfMonth(String monthString) {
		LocalDate date = LocalDate.parse(monthString + "-01");
		int lastDayOfMonth = date.lengthOfMonth();
		return LocalDateTime.of(date, LocalTime.MAX).withDayOfMonth(lastDayOfMonth);
	}

	/**
	 * 获取指定月份的开始和结束时间
	 * @return
	 */
	public static List<LocalDateTime> getMonthDateRange(LocalDate localDate) {
		String format = localDate.format(DatePattern.NORM_MONTH_FORMATTER);
		LocalDateTime start = getStartOfMonth(format);
		LocalDateTime end = getEndOfMonth(format);
		List<LocalDateTime> dateRange = new ArrayList<>();
		dateRange.add(start);
		dateRange.add(end);
		return dateRange;
	}

	/**
	 * 获取时间是周几
	 * @param dayOfWeek
	 * @return
	 */
	public static String getDayOfWeek(DayOfWeek dayOfWeek) {
		Map<DayOfWeek, String> dayOfWeekMap = new HashMap<>();
		dayOfWeekMap.put(DayOfWeek.MONDAY, "星期一");
		dayOfWeekMap.put(DayOfWeek.TUESDAY, "星期二");
		dayOfWeekMap.put(DayOfWeek.WEDNESDAY, "星期三");
		dayOfWeekMap.put(DayOfWeek.THURSDAY, "星期四");
		dayOfWeekMap.put(DayOfWeek.FRIDAY, "星期五");
		dayOfWeekMap.put(DayOfWeek.SATURDAY, "星期六");
		dayOfWeekMap.put(DayOfWeek.SUNDAY, "星期日");
		return dayOfWeekMap.get(dayOfWeek);
	}

	/**
	 * 获取今天的开始和结束时间
	 * @return
	 */
	public static List<LocalDateTime> getTodayDateRange() {
		LocalDateTime now = LocalDateTime.now();
		List<LocalDateTime> todayDateRange = new ArrayList<>();
		todayDateRange.add(now.with(LocalTime.MIN));
		todayDateRange.add(now.with(LocalTime.MAX));
		return todayDateRange;
	}
}
